typedef unsigned int (*copy_sd_mmc_to_mem) (\
			unsigned int  channel, \
			unsigned int  start_block, \
			unsigned short block_size, \
			unsigned int  *trg, \
			unsigned int  init);

void copy_code_to_dram(void)
{
	unsigned long ch;
	void (*BL2)(void);
	unsigned int *copy_dst=0;
	ch = *(volatile unsigned int *)(0xD0037488);
	unsigned char channel = 0;
	
	putc('\n');putc('\r');
	putc('B');putc('L');putc('1');putc(' ');putc('V');putc('e');putc('r');putc(':');
	putc('1');putc('3');putc('0');putc('6');putc('2');putc('6');
	putc('\n');putc('\r');
	putc('S');putc('t');putc('a');putc('r');putc('t');putc(' ');putc('c');putc('p');putc(' ');
	putc('\n');putc('\r');

	// function pointer
	copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem) (*(unsigned int *) (0xD0037F98));

	unsigned int ret;
	
	// channel 0
	if (ch == 0xEB000000)
		channel = 0;

	// channel 2
	else if (ch == 0xEB200000)
		channel = 2;
		
	else
		return;
		
	copy_dst = (unsigned int *)(CONFIG_SYS_TEXT_BASE);
	// 0:channel 0
	// 49 + 32:srouce, BL1 code locate at sector 49 and the fixed length is 0x4000,1 sector = 512 bytes
	// 32 means 0x4000/ 512 
	// COPY_BL2_SIZE/512:# of sector
	// CONFIG_SYS_TEXT_BASE:BL2 link address CONFIG_SYS_TEXT_BASE	
	ret = copy_bl2(channel, 49+32, COPY_BL2_SIZE/512, copy_dst, 0);

	putc('R');putc('u');putc('n');putc('n');putc('i');putc('n');putc('g');putc('!');putc(' ');
	putc('\n');putc('\r');
	
	// skip to DRAM
	BL2 = (void *)CONFIG_SYS_TEXT_BASE;
	dump_hex((unsigned long *)copy_dst, 16);
	putc('\n');putc('\r');
	putc('\n');putc('\r');
	(*BL2)();
}

void board_init_f_mmc()
{
	copy_code_to_dram();	
}
